package com.bjpowernode.shop.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bjpowernode.shop.base.Base;
import com.bjpowernode.shop.constants.CommonConstants;
import com.bjpowernode.shop.constants.QueueConstants;
import com.bjpowernode.shop.domain.SmsLog;
import com.bjpowernode.shop.mapper.SmsLogMapper;
import com.bjpowernode.shop.properties.WxProperties;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Configuration
public class ReceiveWxMsgListener extends Base {

    @Autowired
    private WxProperties wxProperties;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SmsLogMapper smsLogMapper;

    @PostConstruct
    public void initToken() {
        getToken();
    }

    @Scheduled(initialDelay = 1000 * 700, fixedDelay = 1000 * 70)
    public void getToken() {
        // 准备url
        String url = String.format(
                wxProperties.getTokenUrl(),
                wxProperties.getAppId(),
                wxProperties.getAppSecret()
        );

        // 向微信请求token
        String tokenJson = restTemplate.getForObject(url, String.class);

        // 解析json获取token，并存入redis中
        JSONObject jsonObject = JSON.parseObject(tokenJson);

        if (jsonObject.containsKey("access_token")) {
            String token = jsonObject.getString("access_token");
            long expiresIn = jsonObject.getLongValue("expires_in");
            System.out.println("token = " + token);
            System.out.println("expiresIn = " + expiresIn);

            redisTemplate.opsForValue().set(CommonConstants.WX_MSG_TOKEN_PREFIX, token, expiresIn, TimeUnit.SECONDS);
        }
    }


    @RabbitListener(queues = {QueueConstants.WX_MSG_QUEUE})
    public void receiveWxMsgListener(Message message, Channel channel) {
        // 准备url
        String token = String.valueOf(redisTemplate.opsForValue().get(CommonConstants.WX_MSG_TOKEN_PREFIX));
        String url = String.format(wxProperties.getTemplateUrl(), token);

        // 准备请求体
        String wxMsg = new String(message.getBody());

        // 调用微信模板消息api向微信发送请求，让微信向用户发送信息
        String result = restTemplate.postForObject(url, wxMsg, String.class);

        // 解析请求返回值，判断请求是否正常运行
        JSONObject jsonObject = JSON.parseObject(result);

        if (jsonObject.containsKey("errcode")) {
            Integer errcode = (Integer) jsonObject.get("errcode");
            // 若成功发送了
            if (errcode.equals(0)) {
                // ==记录日志消息==
                // 整理内容字段
                Map map = JSON.parseObject(wxMsg, Map.class);
                Map<String, Map<String, String>> data = (Map<String, Map<String, String>>) map.get("data");
                String time = data.get("time").get("value");
                String prod = data.get("prod").get("value");
                String money = data.get("money").get("value");
                String balance = data.get("balance").get("value");
                String content = String.format(
                        wxProperties.getTemplateContent(),
                        time, prod, money, balance
                );

                smsLogMapper.insert(
                        SmsLog.builder()
                                .userId((String) map.get("userId"))
                                .userPhone("wxTemplateMsg")
                                .content(content)
                                .mobileCode("wxTemplateMsg")
                                .type(3)
                                .recDate(new Date())
                                .responseCode(String.valueOf(errcode))
                                .status(1)
                                .build()
                );

                // 手动消费消息
                try {
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
